#include "damechinoise.h"
#include"filtreevenement.h"
#include "ui_damechinoise.h"
#include<QColor>
#include<qmessagebox.h>

DameChinoise::DameChinoise(QWidget *parent) :
    QMainWindow(parent),
    fendame(new Ui::DameChinoise)
{
    fendame->setupUi(this);
    r = 10;
    flag = false;
    fendame->serveurIP->setText("127.0.0.1");
    initEtoile();
    initCouleur();
    filtreEvenement *filtre = new filtreEvenement(this);
    this->installEventFilter(filtre);
    socket = new QTcpSocket(this);
    connect(socket, SIGNAL(readyRead()), this, SLOT(donneesRecues()));
    connect(socket, SIGNAL(connected()), this, SLOT(connecte()));
    connect(socket, SIGNAL(disconnected()), this, SLOT(deconnecte()));
    connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(erreurSocket(QAbstractSocket::SocketError)));

    tailleMessage = 0;

    connect(filtre, SIGNAL(zoneCliquer(int,int)), this, SLOT(dessinerCercle(int,int)));
}

DameChinoise::~DameChinoise()
{
    delete fendame;
}

void DameChinoise::setLabelText(QString texte){
    fendame->pseudo->setText(texte);
}
void DameChinoise::setNumeroPort(int num){
    fendame->serveurPort->setText(QString::number(num));
}

void DameChinoise::paintEvent(QPaintEvent *e){
    QPainter painter(this);
    QPen blackpen(Qt::black);
    blackpen.setWidth(2);
    painter.setPen(blackpen);
    for(int i=0; i<liste.size();i++){
        QPoint p = liste[i].getCentre();
        Cercle *cercle = hash.value((p.y()*1000+p.x()));
        couleur c = cercle->getColor();
        if(c == rouge)painter.setBrush(QBrush(Qt::red));
        if(c == bleu) painter.setBrush(QBrush(Qt::blue));
        if(c == gris) painter.setBrush(QBrush(Qt::gray));
        if(c == jaune) painter.setBrush(QBrush(Qt::yellow));
        if(c == vert) painter.setBrush(QBrush(Qt::green));
        if(c == bleuciel) painter.setBrush(QBrush(Qt::cyan));
        if(c == rose) painter.setBrush(QBrush(Qt::magenta));
        if(c == rougeclair) painter.setBrush(QBrush(QColor(255,100,100)));
        if(c == bleuclair) painter.setBrush(QBrush(QColor(150,150,255)));
        if(c == vertclair) painter.setBrush(QBrush(QColor(180,255,160)));
        if(c == roseclair) painter.setBrush(QBrush(QColor(235,160,255)));
        if(c == bleucielclair) painter.setBrush(QBrush(QColor(210,255,250)));
        if(c == jauneclair) painter.setBrush(QBrush(QColor(255,235,135)));
        painter.drawEllipse(p,r,r);
    }

}


void DameChinoise::initEtoile(){
    QPoint p(200,40);
     QPoint p1((p.x()), (16*2*r+40));
    int px, py, p1y, p1x;

    px = p.x();py=p.y();
    p1x = p1.x(); p1y = p1.y();

    for(int i = 1;i < 14; i++){

        for(int j = 1;j <= i; j++){
           Cercle *a = new Cercle(QPoint(px,py) , gris);
             Cercle *b = new Cercle(QPoint(p1x,p1y) , gris);

             if(!hash.contains(py*1000+px)) {
                 hash.insert((py*1000+px),a );
                 liste << Cercle(QPoint(px,py) , gris);
              }
            if(!hash.contains(p1y*1000+p1x)){
                hash.insert((p1y*1000+p1x), b);
                liste << Cercle(QPoint(p1x,p1y) , gris);
            }

            px = px+ 2*r ;

            p1x =  p1x+ 2*r;

        }
         py = p.y() + 2*r*i;
         p1y = p1.y() - 2*r*i;
         px = p.x() - i*r;
         p1x =  p1.x() - i*r;
    }

}

   void DameChinoise::colorierZoneA(int x, int y, couleur c){

        int  px, py;

        for(int i=0;i<4;i++){
            for(int j=0; j<=i; j++){
                px = x + 2*r*j -r*i;
                py = y + 2*r*i;
                Cercle *cercle = hash.value(py*1000+px);
                if(cercle != NULL) cercle->setColor(c);

            }
        }

   }
    void DameChinoise::colorierZoneB(int x, int y, couleur c){
        int  px, py;

        for(int i=0;i<4;i++){
            for(int j=0; j<=i; j++){
                px = x + 2*r*j -r*i;
                py = y - 2*r*i;
                Cercle *cercle = hash.value(py*1000+px);
                if(cercle != NULL) cercle->setColor(c);

            }
        }


    }

    void DameChinoise::initCouleur(){

    colorierZoneA(200,40,jaune);
    colorierZoneA(290,220,rouge);
     colorierZoneA(110,220,bleu);
    colorierZoneB(110,180,rose);
    colorierZoneB(290,180,bleuciel);
    colorierZoneB(200,360,vert);

 }



    void DameChinoise::gererDeplacement(int x, int y){

        for(int i= 0; i<liste.size();i++){
            Cercle cer = liste[i];
            QPoint p = cer.getCentre();
            float dis = sqrt( (p.x() -x)*(p.x()-x) + (p.y()-y)*(p.y()-y) );
            if(dis < r){
                if(!flag){
                    flag = true;
                    Cercle *cer = hash.value(p.y()*1000+p.x());
                    couleur a = cer->getColor();
                    if(a == rouge) cer->setColor(rougeclair);
                     if(a == bleu) cer->setColor(bleuclair);
                    if(a == jaune) cer->setColor(jauneclair);
                     if(a == vert)cer->setColor(vertclair);
                   if(a == bleuciel) cer->setColor(bleucielclair);
                    if(a == rose) cer->setColor(roseclair);
                    source = p;
                    repaint();
                    return ;
                }
                else{
                    flag = false;
                    Cercle *cerS = hash.value(source.y()*1000+source.x());
                    Cercle *cerD = hash.value(p.y()*1000+p.x());
                    couleur aux;

                    if(cerS->getColor()==rougeclair) cerS->setColor(rouge);
                   if(cerS->getColor()==bleuclair) cerS->setColor(bleu);
                    if(cerS->getColor()==jauneclair) cerS->setColor(jaune);
                    if(cerS->getColor()==bleucielclair) cerS->setColor(bleuciel);
                   if(cerS->getColor()==roseclair) cerS->setColor(rose);
                    if(cerS->getColor()== vertclair) cerS->setColor(vert);


                    if(cerS->getColor()!=gris && cerD->getColor()==gris ){
                        aux  = cerS->getColor();
                        cerS->setColor(cerD->getColor());
                        cerD->setColor(aux);
                        repaint();
                        return ;
                    }
                }
            }

    }

        Cercle *cerS = hash.value(source.y()*1000+source.x());
        if(cerS->getColor()==rougeclair) cerS->setColor(rouge);
        if(cerS->getColor()==bleuclair) cerS->setColor(bleu);
        if(cerS->getColor()==jauneclair) cerS->setColor(jaune);
        if(cerS->getColor()==bleucielclair) cerS->setColor(bleuciel);
        if(cerS->getColor()==roseclair) cerS->setColor(rose);
        if(cerS->getColor()== vertclair) cerS->setColor(vert);
        flag = false;
        repaint();
    }






void DameChinoise::dessinerCercle(int x, int y){
   gererDeplacement(x,y);
}

void DameChinoise::on_boutonConnexion_clicked()
{
    // On annonce sur la fenêtre qu'on est en train de se connecter
    fendame->listeMessages->append(tr("<em>Tentative de connexion en cours...</em>"));
    fendame->boutonConnexion->setEnabled(false);

    socket->abort(); // On désactive les connexions précédentes s'il y en a
    QString temp = fendame->serveurPort->text();
    int port = temp.toInt();
    socket->connectToHost(fendame->serveurIP->text(), port); // On se connecte au serveur demandé
}

// Envoi d'un message au serveur
void DameChinoise::on_boutonEnvoyer_clicked()
{
    QByteArray paquet;
    QDataStream out(&paquet, QIODevice::WriteOnly);

    // On prépare le paquet à envoyer
    QString messageAEnvoyer = tr("<strong>") + fendame->pseudo->text() +tr("</strong> : ") + fendame->message->text();

    out << (quint16) 0;
    out << messageAEnvoyer;
    out.device()->seek(0);
    out << (quint16) (paquet.size() - sizeof(quint16));

    socket->write(paquet); // On envoie le paquet

    fendame->message->clear(); // On vide la zone d'écriture du message
    fendame->message->setFocus(); // Et on remet le curseur à l'intérieur
}

// Appuyer sur la touche Entrée a le même effet que cliquer sur le bouton "Envoyer"
void DameChinoise::on_message_returnPressed()
{
    on_boutonEnvoyer_clicked();
}

// On a reçu un paquet (ou un sous-paquet)
void DameChinoise::donneesRecues()
{
    /* Même principe que lorsque le serveur reçoit un paquet :
    On essaie de récupérer la taille du message
    Une fois qu'on l'a, on attend d'avoir reçu le message entier (en se basant sur la taille annoncée tailleMessage)
    */
    QDataStream in(socket);

    if (tailleMessage == 0)
    {
        if (socket->bytesAvailable() < (int)sizeof(quint16))
             return;

        in >> tailleMessage;
    }

    if (socket->bytesAvailable() < tailleMessage)
        return;


    // Si on arrive jusqu'à cette ligne, on peut récupérer le message entier
    QString messageRecu;
    in >> messageRecu;

    // On affiche le message sur la zone de Chat
    fendame->listeMessages->append(messageRecu);

    // On remet la taille du message à 0 pour pouvoir recevoir de futurs messages
    tailleMessage = 0;
}

// Ce slot est appelé lorsque la connexion au serveur a réussi
void DameChinoise::connecte()
{
   if(fendame->pseudo != NULL){
    QByteArray paquet;
    QDataStream out(&paquet, QIODevice::WriteOnly);

    // On prépare le paquet à envoyer
    QString messageAEnvoyer ="PSEUDO" + fendame->pseudo->text();

    out << (quint16) 0;
    out << messageAEnvoyer;
    out.device()->seek(0);
    out << (quint16) (paquet.size() - sizeof(quint16));

    socket->write(paquet); // On envoie le paquet

    fendame->message->clear(); // On vide la zone d'écriture du message
    fendame->message->setFocus(); // Et on remet le curseur à l'intérieur



    fendame->listeMessages->append(tr("<em>Connexion reussie !</em>"));
    fendame->boutonConnexion->setEnabled(true);
   }
}

// Ce slot est appelé lorsqu'on est déconnecté du serveur
void DameChinoise::deconnecte()
{
    fendame->listeMessages->append(tr("<em>Deconnecte du serveur</em>"));
}

// Ce slot est appelé lorsqu'il y a une erreur
void DameChinoise::erreurSocket(QAbstractSocket::SocketError erreur)
{
    switch(erreur) // On affiche un message différent selon l'erreur qu'on nous indique
    {
        case QAbstractSocket::HostNotFoundError:
            fendame->listeMessages->append(tr("<em>ERREUR : le serveur n'a pas pu etre trouve. Verifiez l'IP et le port.</em>"));
            break;
        case QAbstractSocket::ConnectionRefusedError:
            fendame->listeMessages->append(tr("<em>ERREUR : le serveur a refusé la connexion. Vérifiez si le programme \"serveur\" a bien ete lance. Verifiez aussi l'IP et le port.</em>").toUtf8());
            break;
        case QAbstractSocket::RemoteHostClosedError:
            fendame->listeMessages->append(tr("<em>ERREUR : le serveur a coupé la connexion.</em>").toUtf8());
            break;
        default:
            fendame->listeMessages->append(tr("<em>ERREUR : ") + socket->errorString() + tr("</em>").toUtf8());
    }

    fendame->boutonConnexion->setEnabled(true);
}
